Skip to content

Bump PyMEOS to MEOS 1.4 (work in progress)#81

Draft
estebanzimanyi wants to merge 8 commits into
masterfrom
bump/meos-1.4
Draft

Bump PyMEOS to MEOS 1.4 (work in progress)#81
estebanzimanyi wants to merge 8 commits into
masterfrom
bump/meos-1.4

Conversation

@estebanzimanyi
Copy link
Copy Markdown
Member

@estebanzimanyi estebanzimanyi commented May 14, 2026

Bumps PyMEOS to MEOS 1.4. Pins pymeos-cffi>=1.4.0 and adapts every 1.3 call site to the 1.4 tgeo/tspatial surface:

  • Spatial-relationship family renamed to the 1.4 names (tcontains/tdisjoint/tdwithin/tintersects/ttouches, edisjoint/edwithin/eintersects/etouches, nad/nai/distance, extent_transfn), dropping the restr/atvalue trailing args and the None, None pair on tpoint_at_geom_time/tpoint_minus_geom_time.
  • Set output renamed: geoset_as_ewkt/geoset_as_text/geoset_out -> spatialset_as_ewkt/spatialset_as_text, geoset_round/geoset_srid -> set_round/spatialset_srid (1.4 generalised these from geoset to spatialset; the symbols are confirmed exported by the 1.4 split-header layout, meos_geo.h).
  • STBox.expand_space rewritten to chain (geo|tspatial)_to_stbox with stbox_expand_space (1.4 removed geo_expand_space/tpoint_expand_space).
  • append_instant carries the base type's interpolation.
  • Test workflow builds MEOS with -DCBUFFER=ON -DPOSE=ON and derives the MEOS branch from the package version (stable-X.Y if it exists, else master).
  • Test expectations aligned with the 1.4 semantics for geodetic temporal spatial relationships (geodetic-correct tdwithin; geodetic ttouches is the DE-9IM predicate MEOS does not define for geography, tracked as MobilityDB#1087) and set-theoretic bounding-box adjacency.

State. The PyMEOS side is complete: the full suite is 4492 passed, 0 failed against MEOS 1.4 (locally verified; PyMEOS-CFFI bump/meos-1.4 regenerates cleanly against the 1.4 headers and imports succeed). Black lint is green across the repository.

Remaining CI red is an upstream MEOS dependency, not a PyMEOS defect. The Test jobs build MEOS from MobilityDB/master, which does not yet contain three 1.4 MEOS changes the aligned expectations depend on:

  • geodetic tdwithin (lift to non-point geometries + geodetic kernel) — MobilityDB#1016
  • bbox prefilter ea_dwithin_tgeo_geo — MobilityDB#1015
  • set-theoretic bounding-box adjacency — MobilityDB#1004

Until those reach MobilityDB/master (or a stable-1.4 branch is cut, which the workflow will then pick up automatically), tests/main/tgeogpoint_test.py (geodetic intersects/disjoint/within_distance) and TestTFloatTopologicalFunctions::test_is_adjacent fail against master-built MEOS. They are green against a MEOS built with those three changes. The test expectations are intentionally not masked.

Update the pin to pymeos-cffi >=1.4.0 and version to 1.4.0-alpha-1.
Rename the call sites that switched from MEOS 1.3's tpoint family to
the 1.4 tgeo/tspatial families:

- temporal-output renames: geoset_as_ewkt/as_text/out -> spatialset_*,
  geoset_round -> set_round, geoset_srid -> spatialset_srid,
  pgis_geometry_in/geography_in -> geom_in/geog_in
- tpoint_to_stbox -> tspatial_to_stbox
- tpoint_at_stbox/minus_stbox -> tgeo_at_stbox/minus_stbox
- tpoint_at_geom_time(t, gs, None, None) -> tpoint_at_geom(t, gs)
- tpoint_minus_geom_time(t, gs, None, None) -> tpoint_minus_geom(t, gs)
- tcontains/tdisjoint/tdwithin/tintersects/ttouches_tpoint_* ->
  *_tgeo_*, with the restr/atvalue trailing args dropped
- edisjoint/edwithin/eintersects/etouches_tpoint_* -> *_tgeo_*
- nad/nai/distance_tpoint_* -> *_tgeo_*
- tpoint_extent_transfn -> tspatial_extent_transfn
- spanset_make: dropped normalize/order args (1.4 signature is 1-arg)
- STBox.expand_space: tpoint_expand_space/geo_expand_space were
  removed in 1.4; rebuild as (geo|tspatial)_to_stbox + stbox_expand_space

Pytest collects 4480 tests on this branch. Test execution still
trips on functions that need shape metadata in MEOS-API (e.g.
stbox_quad_split's count output param); follow-up after MEOS-API
adds those entries.
temporal_to_tsequence / temporal_to_tsequenceset now take the
InterpolationType enum directly; PyMEOS was passing the legacy string
form. Pass the IntEnum value (which is already what TInterpolation
holds underneath).

temporal_append_tinstant gained an interp argument in 1.4. It only
matters when the receiver is a TInstant being promoted to a TSequence;
default to STEP because LINEAR is rejected by MEOS for discrete-only
base types like bool/text/integer.
Closes the rename tail surfaced by running the full pytest suite:

- tpoint_as_text / tpoint_as_ewkt -> tspatial_as_text / tspatial_as_ewkt
- tpoint_start_value / tpoint_end_value / tpoint_value_at_timestamptz /
  tpoint_values / tpoint_stboxes -> tgeo_*
- tpoint_srid / tpoint_set_srid -> tspatial_srid / tspatial_set_srid
- teq/tne/ever_eq/ever_ne/always_eq/always_ne_tpoint_point -> *_tgeo_geo
- shortestline_tpoint_* -> shortestline_tgeo_*
- tgeompoint_to_tgeogpoint / tgeogpoint_to_tgeompoint ->
  tgeometry_to_tgeography / tgeography_to_tgeometry
- tfloat_round / tpoint_round -> temporal_round
- tfloat_derivative -> temporal_derivative
- econtains_geo_tpoint -> econtains_geo_tgeo
- tpoint_space_split / tpoint_space_time_split -> tgeo_space_*
- lwproj_transform -> tspatial_transform (signature collapsed; PJ cache
  no longer needed because MEOS 1.4 takes the SRID directly)
- tpoint_expand_space removed; rebuild as tspatial_to_stbox +
  stbox_expand_space
- tpoint_trajectory gained a trailing unary_union bool argument

After these the pytest count is 4464 passed / 16 failed. The 16
remaining failures are: 8 intentional 1.4 restrictions where
tdwithin/etc reject geodetic input ('Only planar coordinates
supported'), 6 string-representation changes (single-segment Step
sequences now render 'Interp=Step;' explicitly), and 2 roundoff
fixture issues. All three categories need committer input on whether
to update test expectations, gate by srid, or report upstream.
Cherry-picks the equivalent of bump/meos-1.3 commits 52e8237 +
d8f9c02 + 22110ef. PyMEOS 1.4 needs the same workflow shape: apt
postgresql-server-dev-16, head_ref-first PyMEOS-CFFI checkout, and
MEOS branch derived from the package version (so 1.4 picks up MEOS
master / future stable-1.4 automatically).
Four assertions had expectations that didn't match the underlying math:

- tests/collections/time/dateset_test.py::TestDateSetComparisons::test_eq
  asserted dateset == other where the two are intentionally different
  (see test_ne immediately after); use the reflexive form.

- tests/main/tfloat_test.py::test_temporal_equal_int passes
  TFloatSeq('[1.5, 2.5]').temporal_equal(1). The fixture expected
  True at start (1.5 == 1 is False), and the SequenceSet variant was
  missing the wrap into TBoolSeqSet that MEOS now emits for linear
  inputs. Updated to all-False, wrapped correctly.

- tests/main/tfloat_test.py::test_temporal_equal_float_1_5
  SequenceSet expected the same 2-segment shape as the Sequence
  variant but MEOS splits at the 12:00 crossing point into 3+1
  segments. Updated to the actual output.

- tests/main/tfloat_test.py::test_temporal_not_equal_int_1 asserted
  False at start and True at end. For [1.5, 2.5] linearly varying,
  != 1 is True everywhere. Updated to all-True.

Pytest now 4482 / 4482 (100%).
The 1.4 surface (PR #81) cdef's meos_cbuffer.h / meos_pose.h /
meos_rgeo.h, which only land in /usr/local/include when the build
enables those features. Without them the cffi step bails on
FileNotFoundError. Mirrors the PyMEOS-CFFI pr_build.yml flags.
MEOS 1.4 added an explicit `interp` argument to
temporal_append_tinstant (1.3 inferred it internally from the
temporal type's continuity). The bump stopgapped it with a hardcoded
InterpolationType.STEP, so appending an instant to a TInstant of a
continuous type (TFloat / TGeomPoint / TGeogPoint / …) promoted it to
a STEP sequence instead of LINEAR.

Restore the 1.3 semantics: derive the argument from the base type's
continuity via a new Temporal._continuous class attribute (True by
default; False on the step-only TInt / TBool / TText, for which MEOS
rejects LINEAR). The argument is consulted by MEOS only on the
instant->sequence promotion and ignored otherwise.

Suite: 4482 passed (was 4479); all 24 append_instant cases green
across every temporal type, no regressions.
@estebanzimanyi estebanzimanyi mentioned this pull request May 20, 2026
@estebanzimanyi estebanzimanyi force-pushed the bump/meos-1.4 branch 2 times, most recently from b2b92e2 to 6c7b804 Compare May 23, 2026 07:14
Companion to the MobilityDB 1.4 surface (geodetic-consistent temporal
spatial relationships and set-theoretic bounding-box adjacency). Three
test-data alignments, each verified against a locally built MEOS 1.4:

* test_temporal_withindist[Discrete Sequence Geo]: the expected was the
  planar answer ({True, True}: sqrt(2) <= 2), produced when geodetic
  dwithin was wrongly computed with the planar kernel. The geodesic
  distance from POINT(1 1) to POINT(2 2) is ~156 876 m, far beyond the
  2 m threshold, so the correct geodetic result is
  {True@2019-09-01, False@2019-09-02}.

* test_temporal_touches -> test_temporal_touches_geodetic_not_supported:
  ttouches is the genuine DE-9IM topological predicate, not tdwithin(0);
  MEOS does not define it for geodetic coordinates. Assert the
  documented, intentional MeosInvalidArgValueError, mirroring the
  in-file test_speed_without_linear_interpolation_throws precedent.

* TestTFloatTopologicalFunctions::test_is_adjacent: MEOS 1.4 computes
  bounding-box adjacency set-theoretically -- two boxes are adjacent
  when their closures meet at a shared boundary value in any dimension,
  independent of the inclusive/exclusive flag. The four [v, v] float
  value-span cases that share their boundary value are therefore now
  adjacent (True); the previous False answers reflected the pre-1.4
  rule that also required exactly one inclusive bound. Integer value
  spans canonicalise to half-open [v, v+1), so the analogous tint cases
  are unaffected and keep returning False.

Make spatial_ref_sys.csv reachable at the MEOS default path in CI. MEOS
reads the CSV from the hard-coded default /usr/local/share on a source
install; on runners whose install prefix differs (macOS arm64 ->
/opt/homebrew) the file is installed elsewhere, so geography SRID
validation failed at collection with "Only lon/lat coordinate systems
are supported in geography". Mirror the file to the default path when
the prefix is not /usr/local.

Also reflow tpoint.py, temporal.py, tfloat_test.py and datespan.py with
Black so the lint job passes across the whole repository.

Verified: full PyMEOS suite 4492 passed against MEOS 1.4.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant